package com.sisgesbyte.web.managedBean.sistema;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;

import com.sisgesbyte.common.ConstantesInternasSistema;
import com.sisgesbyte.services.sistema.MenuSistema;
import com.sisgesbyte.services.sistema.bean.ListaMenuOpcionesResponse;
import com.sisgesbyte.services.sistema.bean.MenuOpcionesBean;
import com.sisgesbyte.web.managedBean.seguridad.TablaRestriccionesMBean;

@ManagedBean
@ViewScoped
public class MenuOpcionesMBean implements Serializable{

	private static final long serialVersionUID = 1L;
	
	@EJB
	private MenuSistema menuSistema;
	private int codModulo;
	private int codMenu;
	private TreeNode selectedNode;
	private TreeNode root;
	private TreeNode[] node;
    private List<MenuOpcionesBean> liRooMenu ;
    private List<MenuOpcionesBean> liChiMenu ;
    private Map<Integer, Integer> auxNumNode ;
    private int numNode;
	private String urlPage;
	
	
	@PostConstruct
	public void init(){
		captureCodModulo();
		captureCodMenu();
		setUrlPage(ConstantesInternasSistema.PAGINA_DEFECTO);
		cargarLista();
	}
	
	public int getCodModulo() {
		return codModulo;
	}

	public void setCodModulo(int codModulo) {
		this.codModulo = codModulo;
	}

	
	public TreeNode getRoot() {
		this.root.setExpanded(true);
		return root;
	}

	
	public TreeNode getSelectedNode() {
		return selectedNode;
	}

	public void setSelectedNode(TreeNode selectedNode) {
		this.selectedNode = selectedNode;
	}
	
	public String getUrlPage() {
		return urlPage;
	}

	public void setUrlPage(String urlPage) {
		this.urlPage = urlPage;
	}
	
	public int getCodMenu() {
		return codMenu;
	}

	public void setCodMenu(int codMenu) {
		this.codMenu = codMenu;
	}

	public void captureCodModulo(){
		//captura el get que contiene el codigo del Modulo
		try{
			FacesContext fc = FacesContext.getCurrentInstance();
			Map<String,String> params = fc.getExternalContext().getRequestParameterMap();
			setCodModulo(Integer.valueOf(params.get("codModulo")));
		}catch(Exception e){
			setCodModulo(0);
		}
	}
	public void captureCodMenu(){
		
		//captura el get que contiene el codigo del menu
		try{
			FacesContext fc = FacesContext.getCurrentInstance();
			Map<String,String> params = fc.getExternalContext().getRequestParameterMap();
			setCodMenu(Integer.valueOf(params.get("codMenu")));
		}catch(Exception e){
			setCodMenu(0);
		}
		
	}
	public void mostrarMenuSistema(ActionEvent event){
		
		setCodModulo(Integer.valueOf(event.getComponent().getAttributes().get("codModuloSistema").toString()));
		if(codModulo>0){
			cargarLista();
		}
	}
	public void mostrarMenuNegocio(ActionEvent event){
		
		setCodModulo(Integer.valueOf(event.getComponent().getAttributes().get("codModuloNegocio").toString()));
		if(codModulo>0){
			cargarLista();
		}
	}
	public void cargarLista(){
		try{
			setUrlPage(ConstantesInternasSistema.PAGINA_DEFECTO);
			//obtenemos las variables de session
			ExternalContext contexto = FacesContext.getCurrentInstance().getExternalContext();
			TablaRestriccionesMBean restriccionesMBean = (TablaRestriccionesMBean) contexto.getSessionMap().get("tablaRestriccionesMBean");
		
			// consultamos el menu 
			ListaMenuOpcionesResponse menuOpciones = menuSistema.listarMenuOpciones(restriccionesMBean.getCodTransaccion(), restriccionesMBean.getCodigoRol(),codModulo );
			//inicializamos variables
			inicializar();
			
			if(Integer.valueOf(menuOpciones.getCodigoRespuesta())==Integer.valueOf(ConstantesInternasSistema.CODIGO_EXITO)){
				
				for (MenuOpcionesBean row : menuOpciones.getMenuOpciones()) {
					if(row.getParentId() == 0 ){
						//Buscamos los menu Padres
						liRooMenu.add(row);
					}else{
						//Buscamos menu Hijos
						liChiMenu.add(row);
					}
				}

				int max = menuOpciones.getMenuOpciones().size();
				if(max > 0){
					node = new TreeNode[max];
					for(MenuOpcionesBean ls : liRooMenu){
						node[numNode] = new DefaultTreeNode(ls , root);
						node[numNode].setExpanded(true);
						auxNumNode.put(ls.getCodMenu(), numNode);
						numNode++;
						
						assignChildren(ls);
					}
				}
				
			}else{
				
				System.out.println("No se encontraron datos para el Menu del modulo Seleccionado");
			}
				
		}catch(Exception e){
			System.out.println("Error al Cargar MenuOpcionesMBean");
		}
		
	}
	 /**
     * Establece los nodos hijos a un árbol menu de forma recursiva.
     *
     * @param father El nodo padre.
     */
	private void assignChildren(MenuOpcionesBean father) {
		List<MenuOpcionesBean> children = new ArrayList<MenuOpcionesBean>();
		children = getMenuByFather(father);
		Iterator<MenuOpcionesBean> iter = children.iterator();

		while (iter.hasNext()) {
			MenuOpcionesBean child = iter.next();
			if ( child.getUrl()== null || child.getUrl() == "" ) {

                node[numNode] = new DefaultTreeNode(child, node[auxNumNode.get(father.getCodMenu())]);
                node[numNode].setExpanded(true);
            } else {
 
                node[numNode] = new DefaultTreeNode("document", child, node[auxNumNode.get(father.getCodMenu())]);
                node[numNode].setExpanded(true);
            }
			 auxNumNode.put(child.getCodMenu(), numNode);
	         numNode++;
	         assignChildren(child);
		}
	 }
	 /**
     * Devuelve una lista de nodos según su padre.
     *
     * @param father El nodo padre.
     * @return La lista de nodos.
     */
	private List<MenuOpcionesBean> getMenuByFather(MenuOpcionesBean father) {
		
		List<MenuOpcionesBean> listR = new ArrayList<MenuOpcionesBean>();
		Iterator<MenuOpcionesBean> it = liChiMenu.iterator();
		 while (it.hasNext()) {
			 MenuOpcionesBean me = it.next();
			 if (me.getParentId().intValue() == father.getCodMenu()) {
	                listR.add(me);
	                it.remove();
	            }
		 }
		return listR;
	}
	
	private void inicializar(){
		liRooMenu = new ArrayList<MenuOpcionesBean>();
		liChiMenu = new ArrayList<MenuOpcionesBean>();
		auxNumNode = new HashMap<Integer, Integer>();
		numNode=0;
		root = new DefaultTreeNode("Root",null);
		root.setExpanded(true);
	}
	
	public void cargarPagina(ActionEvent event){
		//capturamos el atributo 
		String page=event.getComponent().getAttributes().get("urlMenu").toString().trim();
		if(!page.isEmpty()){
			setUrlPage(page.trim());
		}
	}
	
}
